﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;

namespace TestXNA3.Actors
{
    public class Camera : Actor
    {
        public float Fov = 60.0f;
        public float NearClip = 1.0f;
        public float FarClip = 12000.0f;

        public enum ECameraType
        {
            Perspective,
            Ortho
        };

        public ECameraType CameraType = ECameraType.Perspective;

        // Matrices
        private Matrix _projection = Matrix.Identity;
        public Matrix Projection
        {
            get { return _projection; }
        }
        
        private Matrix _view = Matrix.Identity;
        public Matrix View
        {
            get { return _view; }
        }

        private BoundingFrustum _frustum = null;
        public BoundingFrustum Frustum
        {
            get { return _frustum; }
        }

        public Camera()
        {
            _frustum = new BoundingFrustum(_projection);
            _saveable = false;
        }

        public Vector3 Unproject(float x, float y, float z)
        {
            return GameStartup.Graphics.Viewport.Unproject(new Vector3(x, y, z), _projection, _view, Matrix.CreateTranslation(0, 0, 0));
        }

        public Vector3 Unproject(Vector3 v)
        {
            return Unproject(v.X, v.Y, v.Z);
        }

        public Vector3 Project(float x, float y, float z)
        {
            return GameStartup.Graphics.Viewport.Project(new Vector3(x, y, z), _projection, _view, Matrix.CreateTranslation(0, 0, 0));
        }

        public Vector3 Project(Vector3 v)
        {
            return Project(v.X, v.Y, v.Z);
        }

        protected override void preUpdate(float dt)
        {
            base.preUpdate(dt);

            _view = Matrix.CreateLookAt(Location
                , Location + Forward, Up);
            if (CameraType == ECameraType.Perspective)
            {
                _projection = Matrix.CreatePerspectiveFieldOfView(Fov * 3.1416f / 180.0f
                    , (float)GameStartup.Width / (float)GameStartup.Height, NearClip, FarClip);
            }
            if (CameraType == ECameraType.Ortho)
            {
                _projection = Matrix.CreateOrthographic((float)GameStartup.Width, (float)GameStartup.Height, NearClip, FarClip);
            }

            _frustum.Matrix = _view * _projection;
        }

        public override bool Trace(Vector3 start, Vector3 end, bool traceComponents, ref float T)
        {
            return false;
        }
    }
}
